home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Blender 2.49b / blender-2.49b-windows.exe / $_4_ / .blender / scripts / IDPropBrowser.py < prev    next >
Text File  |  2009-08-31  |  13KB  |  524 lines

  1. #!BPY
  2.  
  3. """
  4. Name: 'ID Property Browser'
  5. Blender: 242
  6. Group: 'Help'
  7. Tooltip: 'Browse ID properties'
  8. """
  9.  
  10. __author__ = "Joe Eagar"
  11. __version__ = "0.3.108"
  12. __email__ = "joeedh@gmail.com"
  13. __bpydoc__ = """\
  14.  
  15. Allows browsing, creating and editing of ID Properties
  16. for various ID block types such as mesh, scene, object,
  17. etc.
  18. """
  19.  
  20. # --------------------------------------------------------------------------
  21. # ID Property Browser.
  22. # --------------------------------------------------------------------------
  23. # ***** BEGIN GPL LICENSE BLOCK *****
  24. #
  25. # This program is free software; you can redistribute it and/or
  26. # modify it under the terms of the GNU General Public License
  27. # as published by the Free Software Foundation; either version 2
  28. # of the License, or (at your option) any later version.
  29. #
  30. # This program is distributed in the hope that it will be useful,
  31. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  32. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  33. # GNU General Public License for more details.
  34. #
  35. # You should have received a copy of the GNU General Public License
  36. # along with this program; if not, write to the Free Software Foundation,
  37. # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  38. #
  39. # ***** END GPL LICENCE BLOCK *****
  40. # --------------------------------------------------------------------------
  41.  
  42.  
  43. from Blender import *
  44. from Blender.BGL import *
  45. from Blender.Types import IDGroupType, IDArrayType
  46. import Blender
  47.  
  48. def IsInRectWH(mx, my, x, y, wid, hgt):
  49.     if mx >= x and mx <= x + wid:
  50.         if my >= y and my <= y + hgt:
  51.             return 1
  52.     return 0
  53.  
  54. Button_Back = 1
  55. Button_New = 2
  56. Button_MatMenu = 3
  57. Button_TypeMenu = 4
  58.  
  59. ButStart = 55
  60.  
  61. IDP_String = 0
  62. IDP_Int = 1
  63. IDP_Float = 2
  64. IDP_Array = 5
  65. IDP_Group = 6
  66.  
  67. ButDelStart = 255
  68. #max limit for string input button
  69. strmax = 100
  70.  
  71. State_Normal = 0
  72. State_InArray = 1
  73.  
  74. #IDTypeModules entries are of form [module, active_object_index, module_name]
  75. IDTypeModules = [[Scene, 0, "Scenes"], [Object, 0, "Objects"], [Mesh, 0, "Meshes"]]
  76. IDTypeModules += [[Material, 0, "Materials"], [Texture, 0, "Textures"]]
  77. IDTypeModules += [[Image, 0, "Images"]]
  78.  
  79. class IDArrayBrowser:
  80.     array = 0
  81.     parentbrowser = 0
  82.     buts = 0
  83.     
  84.     def __init__(self):
  85.         self.buts = []
  86.     
  87.     def Draw(self):
  88.         pb = self.parentbrowser
  89.         x = pb.x
  90.         y = pb.y
  91.         width = pb.width
  92.         height = pb.height
  93.         pad = pb.pad
  94.         itemhgt = pb.itemhgt
  95.         cellwid = 65
  96.         y = y + height - itemhgt - pad
  97.         
  98.         Draw.PushButton("Back", Button_Back, x, y, 40, 20)
  99.         y -= itemhgt + pad
  100.         
  101.         self.buts = []
  102.         Draw.BeginAlign()
  103.         for i in xrange(len(self.array)):
  104.             st = ""
  105.             if type(self.array[0]) == float:
  106.                 st = "%.5f" % self.array[i]
  107.             else: st = str(self.array[i])
  108.             
  109.             b = Draw.String("", ButStart+i, x, y, cellwid, itemhgt, st, 30)
  110.             self.buts.append(b)
  111.             x += cellwid + pad
  112.             if x + cellwid + pad > width:
  113.                 x = 0
  114.                 y -= itemhgt + pad
  115.         Draw.EndAlign()
  116.     def Button(self, bval):
  117.         if bval == Button_Back:
  118.             self.parentbrowser.state = State_Normal
  119.             self.parentbrowser.array = 0
  120.             self.buts = []
  121.             Draw.Draw()
  122.             self.array = 0
  123.         elif bval >= ButStart:
  124.             i = bval - ButStart
  125.             st = self.buts[i].val
  126.             n = 0
  127.             if type(self.array[0]) == float:
  128.                 try:
  129.                     n = int(st)
  130.                 except:
  131.                     return
  132.             elif type(self.array[0]) == int:
  133.                 try:
  134.                     n = float(st)
  135.                 except:
  136.                     return
  137.             
  138.             self.array[i] = n
  139.             Draw.Draw()
  140.             
  141.     def Evt(self, evt, val):
  142.         if evt == Draw.ESCKEY:
  143.             Draw.Exit()
  144.     
  145. class IDPropertyBrowser:
  146.     width = 0
  147.     height = 0
  148.     x = 0
  149.     y = 0
  150.     scrollx = 0
  151.     scrolly = 0
  152.     itemhgt = 22
  153.     pad = 2
  154.     
  155.     group = 0
  156.     parents = 0 #list stack of parent groups
  157.     active_item = -1
  158.     mousecursor = 0
  159.     _i = 0
  160.     buts = []
  161.     
  162.     state = 0
  163.     array = 0
  164.     prop = 0
  165.     
  166.     IDList = 0
  167.     idindex = 0
  168.     idblock = 0
  169.     
  170.     type = 0 # attach buildin type() method to class
  171.              # since oddly it's not available to button
  172.              # callbacks! EEK! :(
  173.     
  174.     def __init__(self, idgroup, mat, x, y, wid, hgt):
  175.         self.group = idgroup
  176.         self.prop = idgroup
  177.         self.x = x
  178.         self.y = y
  179.         self.width = wid
  180.         self.height = hgt
  181.         self.mousecursor = [0, 0]
  182.         self.parents = []
  183.         self.idblock = mat
  184.         self.type = type
  185.         
  186.     def DrawBox(self, glmode, x, y, width, height):
  187.         glBegin(glmode)
  188.         glVertex2f(x, y)
  189.         glVertex2f(x+width, y)
  190.         glVertex2f(x+width, y+height)
  191.         glVertex2f(x, y+height)
  192.         glEnd()
  193.             
  194.     def Draw(self):
  195.         global IDTypeModules
  196.         
  197.         #first draw outlining box :)
  198.         glColor3f(0, 0, 0)
  199.         self.DrawBox(GL_LINE_LOOP, self.x, self.y, self.width, self.height)
  200.                 
  201.         itemhgt = self.itemhgt
  202.         pad = self.pad
  203.         x = self.x
  204.         y = self.y + self.height - itemhgt - pad
  205.         
  206.         if self.state == State_InArray:
  207.             self.array.Draw()
  208.             return
  209.         
  210.         plist = []
  211.         self.buts = []
  212.         for p in self.group.iteritems():
  213.             plist.append(p)
  214.         
  215.         #-------do top buttons----------#
  216.         Draw.BeginAlign()
  217.         Draw.PushButton("New", Button_New, x, y, 40, 20)
  218.         x += 40 + pad
  219.         #do the menu button for all materials
  220.         st = ""
  221.         
  222.         blocks =  IDTypeModules[self.IDList][0].Get()
  223.         i = 1
  224.         mi = 0
  225.         for m in blocks:
  226.             if m.name == self.idblock.name:
  227.                 mi = i
  228.             st += m.name + " %x" + str(i) + "|"
  229.             i += 1
  230.         
  231.         self.menubut = Draw.Menu(st, Button_MatMenu, x, y, 100, 20, mi)
  232.         
  233.         x += 100 + pad
  234.         
  235.         st = ""
  236.         i = 0
  237.         for e in IDTypeModules:
  238.             st += e[2] + " %x" + str(i+1) + "|"
  239.             i += 1
  240.         
  241.         cur = self.IDList + 1
  242.         self.idmenu = Draw.Menu(st, Button_TypeMenu, x, y, 100, 20, cur)
  243.         x = self.x
  244.         y -= self.itemhgt + self.pad
  245.         Draw.EndAlign()
  246.         
  247.         
  248.         #-----------do property items---------#
  249.         i = 0
  250.         while y > self.y - 20 - pad and i < len(plist):
  251.             k = plist[i][0]
  252.             p = plist[i][1]
  253.             if i == self.active_item:
  254.                 glColor3f(0.5, 0.4, 0.3)
  255.                 self.DrawBox(GL_POLYGON, x+pad, y, self.width-pad*2, itemhgt)
  256.                 
  257.             glColor3f(0, 0, 0)    
  258.             self.DrawBox(GL_LINE_LOOP, x+pad, y, self.width-pad*2, itemhgt)
  259.             
  260.             glRasterPos2f(x+pad*2, y+5)
  261.             Draw.Text(str(k)) #str(self.mousecursor) + " " + str(self.active_item)) #p.name)
  262.             tlen = Draw.GetStringWidth(str(k))
  263.             
  264.             type_p = type(p)
  265.             if type_p == str:
  266.                 b = Draw.String("", ButStart+i, x+pad*5+tlen, y, 200, itemhgt, p, strmax)
  267.                 self.buts.append(b)
  268.             elif type_p in [int, float]:
  269.                 #only do precision to 5 points on floats
  270.                 st = ""
  271.                 if type_p == float:
  272.                     st = "%.5f" % p
  273.                 else: st = str(p)
  274.                 b = Draw.String("", ButStart+i, x+pad*5+tlen, y, 75, itemhgt, st, strmax)
  275.                 self.buts.append(b)
  276.             else:
  277.                 glRasterPos2f(x+pad*2  +tlen+10, y+5)
  278.                 if type_p == Types.IDArrayType:
  279.                     Draw.Text('(array, click to edit)')
  280.                 elif type_p == Types.IDGroupType:    
  281.                     Draw.Text('(group, click to edit)')
  282.                     
  283.                 
  284.                 self.buts.append(None)
  285.                 
  286.             Draw.PushButton("Del", ButDelStart+i, x+self.width-35, y, 30, 20)
  287.             
  288.             i += 1
  289.             y -= self.itemhgt + self.pad
  290.         
  291.         if len(self.parents) != 0:
  292.             Draw.PushButton("Back", Button_Back, x, y, 40, 20)
  293.             x = x + 40 + pad
  294.             
  295.     def SetActive(self):
  296.         m = self.mousecursor
  297.         itemhgt = self.itemhgt
  298.         pad = self.pad
  299.         
  300.         x = self.x + pad
  301.         y = self.y + self.height - itemhgt - pad - itemhgt
  302.         
  303.         plist = []
  304.         for p in self.group.iteritems():
  305.             plist.append(p)
  306.         
  307.         self.active_item = -1
  308.         i = 0
  309.         while y > self.y and i < len(plist):
  310.             p = plist[i]
  311.             if IsInRectWH(m[0], m[1], x, y, self.width-pad, itemhgt):
  312.                 self.active_item = i
  313.                 
  314.             i += 1
  315.             y -= self.itemhgt + self.pad
  316.         
  317.     def EventIn(self, evt, val):
  318.         if self.state == State_InArray:
  319.             self.array.Evt(evt, val)
  320.         
  321.         if evt == Draw.ESCKEY:
  322.             Draw.Exit()
  323.         if evt == Draw.MOUSEX or evt == Draw.MOUSEY:
  324.             size = Buffer(GL_FLOAT, 4)
  325.             glGetFloatv(GL_SCISSOR_BOX, size)
  326.             if evt == Draw.MOUSEX:
  327.                 self.mousecursor[0] = val - size[0]
  328.             else:
  329.                 self.mousecursor[1] = val - size[1]
  330.             del size
  331.             
  332.             self.SetActive()
  333.             self._i += 1
  334.             if self._i == 5:
  335.                 Draw.Draw()
  336.                 self._i = 0
  337.  
  338.         
  339.         if evt == Draw.LEFTMOUSE and val == 1:
  340.             plist = list(self.group.iteritems())
  341.             a = self.active_item
  342.             if a >= 0 and a < len(plist):
  343.                 p = plist[a]
  344.             
  345.                 basictypes = [IDGroupType, float, str, int]
  346.                 if type(p[1]) == IDGroupType:
  347.                     self.parents.append(self.group)
  348.                     self.group = p[1]
  349.                     self.active_item = -1
  350.                     Draw.Draw()
  351.                 elif type(p[1]) == IDArrayType:
  352.                     self.array = IDArrayBrowser()
  353.                     self.array.array = p[1]
  354.                     self.array.parentbrowser = self
  355.                     self.state = State_InArray
  356.                     Draw.Draw()
  357.                     
  358.         if evt == Draw.TKEY and val == 1:
  359.             try:
  360.                 self.prop['float'] = 0.0
  361.                 self.prop['int'] = 1
  362.                 self.prop['string'] = "hi!"
  363.                 self.prop['float array'] = [0, 0, 1.0, 0]
  364.                 self.prop['int array'] = [0, 0, 0, 0]
  365.                 self.prop.data['a subgroup'] = {"int": 0, "float": 0.0, "anothergroup": {"a": 0.0, "intarr": [0, 0, 0, 0]}}
  366.                 Draw.Draw()
  367.             except:
  368.                 Draw.PupMenu("Can only do T once per block, the test names are already taken!")
  369.                 
  370.                         
  371.     def Button(self, bval):
  372.         global IDTypeModules
  373.         if self.state == State_InArray:
  374.             self.array.Button(bval)
  375.             return
  376.         
  377.         if bval == Button_MatMenu:
  378.             global IDTypeModules
  379.             
  380.             val = self.idindex = self.menubut.val - 1
  381.             i = self.IDList
  382.             block = IDTypeModules[i][0].Get()[val]
  383.             self.idblock = block
  384.             self.prop = block.properties
  385.             self.group = self.prop
  386.             self.active_item = -1
  387.             self.parents = []
  388.             Draw.Draw()
  389.         
  390.         if bval == Button_TypeMenu:            
  391.             i = IDTypeModules[self.idmenu.val-1]
  392.             if len(i[0].Get()) == 0:
  393.                 Draw.PupMenu("Error%t|There are no " + i[2] + "!")
  394.                 return
  395.             
  396.             IDTypeModules[self.IDList][1] = self.idindex
  397.             self.IDList = self.idmenu.val-1
  398.             val = self.idindex = IDTypeModules[self.IDList][1]
  399.             i = self.IDList
  400.             block = IDTypeModules[i][0].Get()[val]
  401.             self.idblock = block
  402.             self.prop = block.properties
  403.             self.group = self.prop
  404.             self.active_item = -1
  405.             self.parents = []
  406.             Draw.Draw()
  407.             
  408.         if bval >= ButDelStart:
  409.             plist = [p for p in self.group]
  410.             prop = plist[bval - ButDelStart]
  411.             del self.group[prop]
  412.             Draw.Draw()
  413.             
  414.         elif bval >= ButStart:
  415.             plist = list(self.group.iteritems())
  416.             
  417.             prop = plist[bval - ButStart]
  418.             print prop
  419.             
  420.             if self.type(prop[1]) == str:
  421.                 self.group[prop[0]] = self.buts[bval - ButStart].val
  422.             elif self.type(prop[1]) == int:
  423.                 i = self.buts[bval - ButStart].val
  424.                 try:
  425.                     i = int(i)
  426.                     self.group[prop[0]] = i
  427.                 except:
  428.                     Draw.Draw()
  429.                     return
  430.                 Draw.Draw()
  431.             elif self.type(prop[1]) == float:
  432.                 f = self.buts[bval - ButStart].val
  433.                 try:
  434.                     f = float(f)
  435.                     self.group[prop[0]] = f
  436.                 except:
  437.                     Draw.Draw()
  438.                     return
  439.                 Draw.Draw()
  440.                 
  441.         elif bval == Button_Back:
  442.             self.group = self.parents[len(self.parents)-1]
  443.             self.parents.pop(len(self.parents)-1)
  444.             Draw.Draw()
  445.         
  446.         elif bval == Button_New:
  447.             name = Draw.Create("untitled")
  448.             stype = Draw.Create(0)
  449.             gtype = Draw.Create(0)
  450.             ftype = Draw.Create(0)
  451.             itype = Draw.Create(0)
  452.             atype = Draw.Create(0)
  453.  
  454.             block = []
  455.             block.append(("Name: ", name, 0, 30, "Click to type in the name of the new ID property"))
  456.             block.append("Type")
  457.             block.append(("String", stype))
  458.             block.append(("Subgroup", gtype))
  459.             block.append(("Float", ftype))
  460.             block.append(("Int", itype))
  461.             block.append(("Array", atype))
  462.             
  463.             retval = Blender.Draw.PupBlock("New IDProperty", block)
  464.             if retval == 0: return
  465.             
  466.             name = name.val
  467.             i = 1
  468.             stop = 0
  469.             while stop == 0:
  470.                 stop = 1
  471.                 for p in self.group:
  472.                     if p == name:
  473.                         d = name.rfind(".")
  474.                         if d != -1:
  475.                             name = name[:d]
  476.                         name = name + "." + str(i).zfill(3)
  477.                         i += 1
  478.                         stop = 0
  479.                 
  480.             type = "String"
  481.             if stype.val: 
  482.                 self.group[name] = ""
  483.             elif gtype.val: 
  484.                 self.group[name] = {}
  485.             elif ftype.val: 
  486.                 self.group[name] = 0.0
  487.             elif itype.val: 
  488.                 self.group[name] = 0 #newProperty("Int", name, 0)
  489.             elif atype.val: 
  490.                 arrfloat = Draw.Create(1)
  491.                 arrint = Draw.Create(0)
  492.                 arrlen = Draw.Create(3)
  493.                 block = []
  494.                 block.append("Type")
  495.                 block.append(("Float", arrfloat, "Make a float array"))
  496.                 block.append(("Int", arrint, "Make an integer array"))
  497.                 block.append(("Len", arrlen, 2, 200))
  498.                 
  499.                 if Blender.Draw.PupBlock("Array Properties", block):
  500.                     if arrfloat.val:
  501.                         tmpl = 0.0
  502.                     elif arrint.val:
  503.                         tmpl = 0
  504.                     else:
  505.                         return
  506.                     
  507.                     self.group[name] = [tmpl] * arrlen.val
  508.  
  509.                 
  510.     def Go(self):
  511.         Draw.Register(self.Draw, self.EventIn, self.Button)
  512.  
  513. scenes = Scene.Get()
  514.  
  515. size = Window.GetAreaSize()
  516. browser = IDPropertyBrowser(scenes[0].properties, scenes[0], 2, 2, size[0], size[1])
  517. browser.Go()
  518.  
  519. #a = prop.newProperty("String", "hwello!", "bleh")
  520. #b = prop.newProperty("Group", "subgroup")
  521.  
  522. #for p in prop:
  523.     #print p.name
  524.